#!/bin/bash
# version: v1
# update: 20210719 更新时间同步服务逻辑
# 此脚本用于k8s环境初始化, 安装k8s版本为1.21.3, docker版本为20.10.7

pub() {
   time="$(date +%Y-%m-%d-%H%M%S)"
   logfile="/tmp/${time}"
}

set_hostname(){
   hostnamectl  set-hostname hx-k8s-dev-"$(ip -4 a|grep inet|grep -v 127.0.0.1|grep -v inet6|awk '{print $2}'|tr -d 'addr:'|awk -F'/' '{print $1}')"
}

check_network() {
   echo -e "\033[1;5;32;4m  ++++++开始检查网络状态++++++ \033[0m"
   ping -c 2 -i 0.1 www.baidu.com >/dev/null 2>&1
   temp1=$?
   ping -c 2 -i 0.1 www.taobao.com >/dev/null 2>&1
   temp2=$?
   if [ ! ${temp1} -eq 0 ] && [ ! ${temp2} -eq 0 ]; then
      echo -e "\033[31m 服务器无法访问外网，scripts退出!!! \033[0m"
      exit 1
   fi
   echo -e "\033[1;5;32;4m  ++++++网络状态检查完成，状态正常++++++ \033[0m"
}

init_disk () {
   echo -e "\033[1;5;32;4m  ++++++开始格式化分区++++++ \033[0m"
   # 磁盘分区
   echo "n
   p
   1


   w
   " | fdisk /dev/sdb
   temp1=$?
   # xfs格式化磁盘
   sleep 5 && mkfs.xfs /dev/sdb1
   temp2=$?
   # 挂载到 /data 目录
   mkdir -p  /data && mount /dev/sdb1 /data && mount  -a
   temp3=$?
   # 写入开机加载 /etc/fstab
   echo "UUID=$(blkid |grep sdb1|grep UUID |awk -F '"' '{print $2}') /data                   xfs     defaults        0 0" >> /etc/fstab
   if [ ! ${temp1} -eq 0 ] && [ ! ${temp2} -eq 0 ] && [ ! ${temp3} -eq 0 ]; then
      echo -e "\033[31m 格式化分区失败，scripts退出!!! \033[0m"
      echo "格式化分区失败!!!" >>${logfile}.err
      exit 1
   fi
   echo "格式化分区已经完成!!!" >>${logfile}.ok
   echo -e "\033[1;5;32;4m  ++++++格式化分区完成，状态正常++++++ \033[0m"
}

install_soft() {
   echo -e "\033[1;5;32;4m  ++++++开始安装系统基础软件++++++ \033[0m"
   /usr/bin/yum -y install rsync ntpdate inotify-tools telnet nc net-tools nfs-utils autoconf automake bind-utils cmake dmidecode ftp gcc-c++ gdb glibc-devel iftop libaio-devel libevent-devel libtool lrzsz lsof man ncurses-devel ntp parted patch pciutils perl psmisc sysstat tree unzip vim vixie-cron wget zip zlib-devel >/dev/null 2>&1
   if [ $? -eq 0 ]; then
      echo "基础软件已经安装!!!" >>${logfile}.ok
      echo -e "\033[1;5;32;4m  ++++++系统基础软件安装完成++++++ \033[0m"
   else
      echo "基础软件安装失败!!!" >>${logfile}.err
   fi
}

ulimit_nofile() {
   #优化每用户创建的软硬连接数
   echo -e "\033[1;5;32;4m  ++++++开始优化每用户创建的软硬连接数++++++ \033[0m"
   grep "65535" /etc/security/limits.conf >/dev/null 2>&1
   if [ ! $? -eq 0 ]; then
      cat >>/etc/security/limits.conf <<EOF
*  soft nofile 65535
*  hard nofile 65535
*  soft noproc  65536
*  hard noproc  65536
EOF
      echo "ulimit_nofile已经优化!" >>${logfile}.ok
   fi

   #使对/etc/security/limits.conf的设置起效
   ulimit -n >/dev/null 2>&1

   echo -e "\033[1;5;32;4m  ++++++优化每用户创建的软硬连接数完成++++++ \033[0m"
}

sshd() {
   echo -e "\033[1;5;32;4m  ++++++开始优化sshd服务++++++ \033[0m"
   cp -rf /etc/ssh/sshd_config /etc/ssh/sshd_config_bak
   sed -i "s@^GSSAPIAuthentication yes@GSSAPIAuthentication no@g" /etc/ssh/sshd_config
   sed -i "s@^#UseDNS yes@UseDNS no@g" /etc/ssh/sshd_config
   #重启sshd服务
   systemctl enable sshd.service
   systemctl restart sshd >/dev/null 2>&1
   if [ $? -eq 0 ]; then
      echo "sshd服务,已优化并正常启动!!!" >>${logfile}.ok
      echo -e "\033[1;5;32;4m  ++++++优化sshd服务完成++++++ \033[0m"
   else
      echo "sshd服务优化后无法启动，请手动检查!!!" >>${logfile}.err
   fi
}

bash_history() {
   echo -e "\033[1;5;32;4m  ++++++开始优化history记录++++++ \033[0m"
   sed -i '/HISTSIZE/d' ~/.bashrc
   sed -i '/HISTFILESIZE/d' ~/.bashrc
   sed -i '/PROMPT_COMMAND/d' ~/.bashrc
   sed -i '/HISTTIMEFORMAT/d' ~/.bashrc
   sed -i '/HISTCONTROL/d' ~/.bashrc
   cat >>~/.bashrc <<EOF
export HISTCONTROL=ignorespace
export HISTSIZE=10000
export HISTFILESIZE=10000
export PROMPT_COMMAND="history -a"
export HISTTIMEFORMAT="[%F %T][$(whoami)]  "
EOF
   echo "history已经优化!" >>${logfile}.ok
   echo -e "\033[1;5;32;4m  ++++++优化history记录完成++++++ \033[0m"
}

yum_upgrade() {
   echo -e "\033[1;5;32;4m  ++++++开始使用upgrade更新系统++++++ \033[0m"
   echo "begin yum -y upgrade..."
   yum -y upgrade >/dev/null 2>&1
   if [ $? -eq 0 ]; then
      echo "yum -y upgrade已完成!" >>${logfile}.ok
      echo -e "\033[1;5;32;4m  ++++++使用upgrade更新系统完成++++++ \033[0m"
   else
      echo "yum -y upgrade失败!" >>${logfile}.err
      echo -e "\033[1;5;32;4m  ++++++使用upgrade更新系统失败，请检查++++++ \033[0m"
   fi
}

disabled_ipv6() {
   echo -e "\033[1;5;32;4m  ++++++开始禁用ipv6网络++++++ \033[0m"
   modprobe bridge
   cp -rf /etc/sysctl.conf /etc/sysctl.conf_bak
   sed -i '/NETWORKING_IPV6/d' /etc/sysconfig/network >/dev/null 2>&1
   echo "NETWORKING_IPV6=no" >>/etc/sysconfig/network
   sed -i '/net.ipv6.conf.all.disable_ipv6/d' /etc/sysctl.conf
   echo "net.ipv6.conf.all.disable_ipv6 = 1" >>/etc/sysctl.conf
   sed -i '/net.ipv6.conf.default.disable_ipv6/d' /etc/sysctl.conf
   echo "net.ipv6.conf.default.disable_ipv6 = 1" >>/etc/sysctl.conf
   /sbin/sysctl -p | grep "net.ipv6.conf.all.disable_ipv6" >/dev/null 2>&1
   if [ $? -eq 0 ]; then
      echo "ipv6 已经关闭!!!" >>${logfile}.ok
      echo -e "\033[1;5;32;4m  ++++++ipv6网络已禁用++++++ \033[0m"
   else
      echo "ipv6 关闭失败!!!" >>${logfile}.err
   fi
}

# 禁用SELINUX
disabled_selinux() {
   echo -e "\033[1;5;32;4m  ++++++开始禁用防火墙++++++ \033[0m"
   #变量声明
   selinx_config="/etc/selinux/config"
   #备份selinux配置
   cp -rf ${selinx_config} ${selinx_config}_${time}
   setenforce 0 >/dev/null 2>&1
   sed -i 's/SELINUX=enforcing/SELINUX=disabled/g' ${selinx_config}
   echo "selinux已关闭" >>${logfile}.ok
   systemctl stop firewalld >/dev/null 2>&1
   temp1=$?
   systemctl disable firewalld >/dev/null 2>&1
   temp2=$?
   if [ ${temp1} -eq 0 ] && [ ${temp2} -eq 0 ]; then
      echo "iptables 服务已关闭,并设置开启不自启动!" >>${logfile}.ok
   else
      echo "iptables 服务关闭失败!" >>${logfile}.ok
   fi
   echo -e "\033[1;5;32;4m  ++++++防火墙已全部禁用++++++ \033[0m"
}

ntpdate() {
   echo -e "\033[1;5;32;4m  ++++++开始更新ntpd服务++++++ \033[0m"
   systemctl disable chronyd.service
   ln -sf /usr/share/zoneinfo/Asia/Shanghai /etc/localtime
   ping -c 2 -i 0.1 Time_Server >/dev/null 2>&1  # 内网授时服务器
   temp1=$?
   if [ ${temp1} -eq 0 ];then
      echo "05 * * * * /usr/sbin/ntpdate Time_Server" >> /var/spool/cron/root
      systemctl restart rsyslog
   else
      echo "05 * * * * /usr/sbin/ntpdate ntp1.aliyun.com" >> /var/spool/cron/root
      systemctl restart rsyslog
   fi
   if [ $? -eq 0 ]; then
      echo -e "\033[1;5;32;4m  ++++++ntpd服务更新完成++++++ \033[0m"
   else
      echo "ntpd服务更新失败!!! " >>${logfile}.err
   fi
}

stop_swap() {
   # 关闭Swap
   echo -e "\033[1;5;32;4m  ++++++开始关闭swap++++++ \033[0m"
   echo '0' > /proc/sys/vm/swappiness
   swapoff -a
   temp1=$?
   sed -i 's/.*swap.*/#&/' /etc/fstab
   temp2=$?
   if [ ${temp1} -eq 0 ] && [ ${temp2} -eq 0 ]; then
      echo "swap分区已经关闭!" >>${logfile}.ok
      echo -e "\033[1;5;32;4m  ++++++swap关闭完成++++++ \033[0m"
   else
      echo "swap分区关闭失败!" >>${logfile}.ok
   fi
}

# kube-proxy使用ipvs模式, 开启ipvs
config_ipvs() {
   yum install -y ipvsadm
   cat >/etc/sysconfig/modules/ipvs.modules <<EOF
#!/bin/bash
modprobe -- ip_vs
modprobe -- ip_vs_rr
modprobe -- ip_vs_wrr
modprobe -- ip_vs_sh
modprobe -- nf_conntrack_ipv4
EOF
   chmod 755 /etc/sysconfig/modules/ipvs.modules && bash /etc/sysconfig/modules/ipvs.modules && lsmod | grep -e ip_vs -e nf_conntrack_ipv4
}

# 开启端口转发，关闭swappiness
start_forward() {
   echo -e "\033[1;5;32;4m  ++++++开启端口转发，关闭swappiness功能++++++ \033[0m"
   modprobe br_netfilter
   cat >/etc/sysctl.d/k8s.conf <<EOF
net.bridge.bridge-nf-call-ip6tables = 1
net.bridge.bridge-nf-call-iptables = 1
net.ipv4.ip_forward = 1
vm.swappiness = 0
EOF
   sysctl -p /etc/sysctl.d/k8s.conf
   if [ $? -eq 0 ]; then
      echo "开启端口转发成功! " >>${logfile}.ok
      echo -e "\033[1;5;32;4m  ++++++端口转发，关闭swappiness功能开启完成++++++ \033[0m"
   else
      echo "开启端口转发，关闭swappiness is not ok!失败!!! " >>${logfile}.err
   fi
}

install_core() {
   # 导入ELRepo公钥
   rpm --import https://www.elrepo.org/RPM-GPG-KEY-elrepo.org
   # 安装ELRepo
   yum install https://www.elrepo.org/elrepo-release-7.el7.elrepo.noarch.rpm -y
   temp1=$?
   # 查看ELRepo提供的内核版本，其中lt表示longterm，即长期支持的内核; ml表示表示mainline，即当前主线的内核
   # yum --disablerepo="*" --enablerepo="elrepo-kernel" list available
   # 安装kernel-lt
   yum --disablerepo='*' --enablerepo=elrepo-kernel install kernel-lt  -y
   temp2=$?
   # 查看启动器
   # awk -F\' '$1=="menuentry " {print i++" : " $2}' /etc/grub2.cfg
   # 设置使用新内核
   grub2-set-default 0 && grub2-mkconfig -o /etc/grub2.cfg
   grubby --args="user_namespace.enable=1" --update-kernel="$(grubby --default-kernel)"
   temp3=$?
   if [ ${temp1} -eq 0 ] && [ ${temp2} -eq 0 ] && [ ${temp3} -eq 0 ]; then
      echo "内核升级完成!! 需要重启!!!" >>${logfile}.ok
      echo -e "\033[1;5;32;4m  ++++++swap关闭完成++++++ \033[0m"
   else
      echo "内核升级失败!" >>${logfile}.ok
   fi
}

# 安装docker, kubernetes依赖软件
install_k8s_soft() {
   # 安装docker 18.09.3
   echo -e "\033[1;5;32;4m  ++++++开始安装docker++++++ \033[0m"
   yum install -y yum-utils

   yum remove docker docker-client docker-client-latest docker-common docker-latest docker-latest-logrotate docker-logrotate docker-engine docker-ce* -y

   yum-config-manager --add-repo https://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo

   yum install docker-ce-20.10.7 docker-ce-cli-20.10.7 containerd.io -y

   systemctl enable docker
   systemctl start docker
   systemctl status docker

   # 配置docker使用overlay2存储
   mkdir /etc/docker
   cat >/etc/docker/daemon.json <<EOF
{
    "insecure-registries":["Your Registry"],
    "data-root":"/data/docker",
    "exec-opts": ["native.cgroupdriver=systemd"],
    "storage-driver": "overlay2",
    "bip":"172.31.0.1/22",
    "log-driver": "json-file",
    "log-opts": {
        "max-size": "100m"
    }
}
EOF

   systemctl restart docker && systemctl status docker
   echo -e "\033[1;5;32;4m  ++++++docker安装完成++++++ \033[0m"

   echo -e "\033[1;5;32;4m  ++++++开始安装kubelet, kubeadm, kubectl++++++ \033[0m"
   # 配置yum源
   cat >/etc/yum.repos.d/kubernetes.repo <<EOF
[kubernetes]
name=Kubernetes
baseurl=http://mirrors.aliyun.com/kubernetes/yum/repos/kubernetes-el7-x86_64
enabled=1
gpgcheck=0
repo_gpgcheck=0
gpgkey=http://mirrors.aliyun.com/kubernetes/yum/doc/yum-key.gpg
      http://mirrors.aliyun.com/kubernetes/yum/doc/rpm-package-key.gpg
EOF

   # 安装对应版本的kubelet，kubeadm，kubectl

   yum makecache fast && yum install -y kubelet-1.21.3 kubectl-1.21.3 kubeadm-1.21.3 --disableexcludes=kubernetes

   # 配置kubectl命令补全
   yum install -y bash-completion
   cat >>/root/.bashrc <<EOF
export KUBECONFIG=/etc/kubernetes/admin.conf
source <(kubectl completion bash)
EOF

   systemctl daemon-reload && systemctl restart kubelet && systemctl status kubelet && systemctl enable kubelet.service

   echo "install_k8s soft is successfully!" >>${logfile}.ok
   echo -e "\033[1;5;32;4m  ++++++安装kubelet, kubeadm, kubectl完成++++++ \033[0m"
   echo -e "\033[1;5;32;4m  ++++++kubernetes相关依赖软件安装完成++++++ \033[0m"
}

summary() {
   if [ -s ${logfile}.ok ]; then
      num=$(cat ${logfile}.ok | wc -l)
      echo "#################################"
      echo "#################################"
      echo "以下${num}项已优化"
      for i in $(seq ${num}); do
         line="$(head -$i ${logfile}.ok | tail -1)"
         echo -e "\033[32m${i}.${line} \033[0m"
      done
   else
      echo "~~~~~~~~~~初始化有问题请查看~~~~~~~~~~"
   fi

   if [ -f ${logfile}.err ] && [ -s ${logfile}.err ]; then
      num=$(cat ${logfile}.err | wc -l)
      echo "---------------------------------"
      echo "---------------------------------"
      echo "以下${num}项优化有问题:"
      for i in $(seq ${num}); do
         line="$(head -$i ${logfile}.err | tail -1)"
         echo -e "\033[32m${i}.${line} \033[0m"
      done
   else
      echo "~~~~~~~~~~初始化完成没有问题~~~~~~~~~~"
   fi
}

main() {
   pub
   set_hostname
   disabled_selinux
   check_network
   init_disk
   install_soft
   disabled_ipv6
   config_ipvs
   ntpdate
   sshd
   ulimit_nofile
   bash_history
   yum_upgrade
   stop_swap
   start_forward
   install_core
   install_k8s_soft
   sleep 5
   summary
}

#触发
main